package cross;

import GA.Chromosome;
import GA.Cross;
import antTrail.AntTrailChromosome;
import antTrail.ProgramTree;

public class RandomSwap extends Cross {

	public RandomSwap(double crossProb, int chromosomeLenght) {
		super(crossProb, chromosomeLenght, ReplacementType.getBetters);
	}

	protected Chromosome[] cross(Chromosome parent1, Chromosome parent2) {
		// Get trees from both parents
		ProgramTree child1_tree = ((AntTrailChromosome)parent1).getTree().clone();
		ProgramTree child2_tree = ((AntTrailChromosome)parent2).getTree().clone();
		
		// Random point on each tree's total nodes (min 1)
		int crossPoint1 = 1 + GA.Algorithm.random.nextInt(child1_tree.getNum_nodes()-1);
		int crossPoint2 = 1 + GA.Algorithm.random.nextInt(child2_tree.getNum_nodes()-1);
		
		// Get both sub_trees
		ProgramTree child1_subTree = child1_tree.getSubTree(crossPoint1);
		ProgramTree child2_subTree = child2_tree.getSubTree(crossPoint2);
		
		// Swap sub_trees
		child1_tree.replaceSubTree(crossPoint1, child2_subTree);
		child2_tree.replaceSubTree(crossPoint2, child1_subTree);
		
		// Swap sub_trees's parents
		ProgramTree aux = child1_subTree.getParent();
		child1_subTree.setParent(child2_subTree.getParent());
		child2_subTree.setParent(aux);
		
		// Create & evaluate children from swapped trees 
		AntTrailChromosome child1 = (AntTrailChromosome) parent1.clone();
		if (child1_tree.getDepth() <= child1.getDepthMax())
			child1.setTree(child1_tree);
		child1.evaluate();
		AntTrailChromosome child2 = (AntTrailChromosome) parent2.clone();
		if (child1_tree.getDepth() <= child1.getDepthMax())
			child1.setTree(child2_tree);
		child1.evaluate();
		
		return new Chromosome[] {child1, child2};
	}

}
